﻿using AjaxControlToolkit;
using System;
using System.Configuration;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Oracle.DataAccess.Client;

namespace Testify
{
    public partial class GradedTest : System.Web.UI.Page
    {
        int questionNumber;

        #region _Event-Handling_

        protected void Page_Load(object sender, EventArgs e)
        {
            questionNumber = 0;
        }

        protected void dsQuestions_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
        {
            e.Command.Parameters["p_Offset"].Value = questionNumber;
        }

        protected void grdQuestions_DataBound(object sender, EventArgs e)
        {
            questionNumber += ((GridView)sender).Rows.Count;
        }

        protected void grdQuestions_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            const string TRUE_FALSE            = "1";
            const string MULTIPLE_CHOICE       = "2";
            const string FILL_IN_THE_BLANK     = "3";
            const string SHORT_ANSWER          = "4";
            const string CHOOSE_ALL_THAT_APPLY = "5";
            const string MATCHING              = "6";
            const string MODIFIED_TRUE_FALSE   = "7";
            const string PLEDGE_STATEMENT      = "8";
            const string ESSAY                 = "9";

            const string CHOICE_TRUE  = "1";
            const string CHOICE_FALSE = "0";

            const int CREDIT = 0;
            const int WEIGHT = 1;

            const char DELIMITER_CHOOSE_ALL_THAT_APPLY = ',';

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                DataRowView   drvQuestion = (DataRowView)  e.Row.DataItem;
                SqlDataSource dsChoices   = (SqlDataSource)e.Row.Cells[0].FindControl("dsChoices");

                string[] creditAndWeight = ((Label)e.Row.Cells[0].FindControl("lblQuestionText")).Text.Split(']')[0].Replace("[", String.Empty).Split('/');
                ((HtmlTableCell)e.Row.Cells[0].FindControl("thYourResponse")).Style.Add(HtmlTextWriterStyle.Color,
                    (creditAndWeight[CREDIT] == creditAndWeight[WEIGHT] ? "Lime" : "Red"));

                switch (Convert.ToString(drvQuestion["question_type_id"]))
                {
                    case TRUE_FALSE:
                        dsChoices.SelectCommand = @"
SELECT choice_id, choice_text
  FROM singularity.choice c
 WHERE c.question_id IS NULL
   AND c.segment_id  IS NULL
   AND c.choice_maint != 'D'";

                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trTrueFalse")).Visible = true;

                        string response_tf = getStudentResponse(Convert.ToString(drvQuestion["question_id"]));
                        if (!String.IsNullOrEmpty(response_tf))
                            showTrueFalse("rblTrueFalseResponse", e.Row).SelectedValue = response_tf;

                        string answer_tf   = getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"]));
                        if (!String.IsNullOrEmpty(answer_tf))
                            showTrueFalse("rblTrueFalseAnswer",   e.Row).SelectedValue = answer_tf;
                        break;
                    case MULTIPLE_CHOICE:
                        dsChoices.SelectCommand = @"
SELECT choice_id, choice_text
  FROM singularity.choice c
 WHERE c.question_id = :p_QuestionID
   AND c.choice_maint != 'D'
 ORDER BY c.choice_sort_order";
                        dsChoices.SelectParameters.Add("p_QuestionID", Convert.ToString(drvQuestion["question_id"]));

                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trMultipleChoice")).Visible = true;

                        string response_mc = getStudentResponse(Convert.ToString(drvQuestion["question_id"]));
                        if (!String.IsNullOrEmpty(response_mc))
                            showMultipleChoice("rblMultipleChoiceResponse", e.Row).SelectedValue = response_mc;

                        string answer_mc   = getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"]));
                        if (!String.IsNullOrEmpty(answer_mc))
                            showMultipleChoice("rblMultipleChoiceAnswer",   e.Row).SelectedValue = answer_mc;
                        break;
                    case FILL_IN_THE_BLANK:
                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trFillInTheBlank")).Visible = true;
                        showFillInTheBlank("txtFillInTheBlankResponse", e.Row).Text = getStudentResponse  (                   Convert.ToString(drvQuestion["question_id"]));
                        showFillInTheBlank("txtFillInTheBlankAnswer",   e.Row).Text = getCorrectAnswerText(getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"])));
                        break;
                    case SHORT_ANSWER:
                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trShortAnswer")).Visible = true;
                        showShortAnswer("txtShortAnswerResponse", e.Row).Text = getStudentResponse  (                   Convert.ToString(drvQuestion["question_id"]));
                        showShortAnswer("txtShortAnswerAnswer",   e.Row).Text = getCorrectAnswerText(getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"])));
                        break;
                    case CHOOSE_ALL_THAT_APPLY:
                        dsChoices.SelectCommand = @"
SELECT choice_id, choice_text
  FROM singularity.choice c
 WHERE c.question_id   = :p_QuestionID
   AND c.choice_maint != 'D'
   AND c.choice_id    != (SELECT questions.getQuestionAnswerID(p_QuestionID => :p_QuestionID) FROM dual)
 ORDER BY c.choice_sort_order";
                        dsChoices.SelectParameters.Add("p_QuestionID", Convert.ToString(drvQuestion["question_id"]));

                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trChooseAllThatApply")).Visible = true;
                        
                        CheckBoxList cblChooseAllThatApplyResponse = showChooseAllThatApply("cblChooseAllThatApplyResponse", e.Row);
                        string[] responses = getStudentResponse  (                   Convert.ToString(drvQuestion["question_id"])).Split(DELIMITER_CHOOSE_ALL_THAT_APPLY);
                        
                        for (int i = 0; i < responses.Length; i++)
                            for (int j = 0; j < cblChooseAllThatApplyResponse.Items.Count; j++)
                                if (responses[i] == cblChooseAllThatApplyResponse.Items[j].Value) {
                                    cblChooseAllThatApplyResponse.Items[j].Selected = true;
                                    break;
                                }

                        CheckBoxList cblChooseAllThatApplyAnswer   = showChooseAllThatApply("cblChooseAllThatApplyAnswer",   e.Row);
                        string[] answers   = getCorrectAnswerText(getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"]))).Split(DELIMITER_CHOOSE_ALL_THAT_APPLY);
                        
                        for (int i = 0; i < answers.Length; i++)
                            for (int j = 0; j < cblChooseAllThatApplyAnswer.Items.Count; j++)
                                if (answers[i] == cblChooseAllThatApplyAnswer.Items[j].Value) {
                                    cblChooseAllThatApplyAnswer.Items[j].Selected = true;
                                    break;
                                }
                        break;
                    case MATCHING:
                        dsChoices.SelectCommand = @"
SELECT choice_id, choice_text
  FROM singularity.choice c
 WHERE c.segment_id = :p_SegmentID
   AND c.choice_maint != 'D'
 ORDER BY choice_sort_order";
                        dsChoices.SelectParameters.Add("p_SegmentID", Convert.ToString(drvQuestion["segment_id"]));

                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trMatching")).Visible = true;
                        showMatching("ddlMatchingResponse", e.Row).SelectedValue = getStudentResponse(Convert.ToString(drvQuestion["question_id"]));
                        showMatching("ddlMatchingAnswer",   e.Row).SelectedValue = getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"]));
                        break;
                    case MODIFIED_TRUE_FALSE:
                        dsChoices.SelectCommand = @"
SELECT choice_id, choice_text
  FROM singularity.choice c
 WHERE c.question_id IS NULL
   AND c.segment_id  IS NULL
   AND c.choice_maint != 'D'";

                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trTrueFalse"     )).Visible = true;
                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trFillInTheBlank")).Visible = true;

                        string response_mtf = getStudentResponse(Convert.ToString(drvQuestion["question_id"]));
                        if (!String.IsNullOrEmpty(response_mtf) && (showTrueFalse("rblTrueFalseResponse", e.Row).SelectedValue = (response_mtf == CHOICE_TRUE ? CHOICE_TRUE : CHOICE_FALSE)) == CHOICE_FALSE)
                            showFillInTheBlank("txtFillInTheBlankResponse", e.Row).Text =                      response_mtf;

                        string answer_mtf   = getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"]));
                        if (!String.IsNullOrEmpty(answer_mtf)   && (showTrueFalse("rblTrueFalseAnswer",   e.Row).SelectedValue = (answer_mtf   == CHOICE_TRUE ? CHOICE_TRUE : CHOICE_FALSE)) == CHOICE_FALSE)
                            showFillInTheBlank("txtFillInTheBlankAnswer",   e.Row).Text = getCorrectAnswerText(answer_mtf);
                        break;
                    case PLEDGE_STATEMENT:
                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trPledgeStatement")).Visible = true;
                        showPledgeStatement("txtPledgeStatementResponse", e.Row).Text = getStudentResponse(Convert.ToString(drvQuestion["question_id"]));
                        showPledgeStatement("txtPledgeStatementAnswer",   e.Row).Text = getStudentName();
                        break;
                    case ESSAY:
                        ((HtmlTableCell)e.Row.Cells[0].FindControl("thCorrectAnswer")).Visible = false;

                        ((HtmlTableRow)e.Row.Cells[0].FindControl("trEssayResponse")).Visible = true;
                        //((HtmlTableRow)e.Row.Cells[0].FindControl("trCorrectAnswerEssay")).Visible = true;
                        //((HtmlTableRow)e.Row.Cells[0].FindControl("trEssayAnswer"  )).Visible = true;
                        showEssay("txtEssayResponse", e.Row).Text = getStudentResponse  (                   Convert.ToString(drvQuestion["question_id"]));
                        //showEssay("txtEssayAnswer",   e.Row).Text = getCorrectAnswerText(getCorrectAnswerID(Convert.ToString(drvQuestion["question_id"])));
                        break;
                    default:
                        break;
                }
            }
        }

        #endregion

        #region _Show Functions_

        protected RadioButtonList showMultipleChoice(string controlID, GridViewRow row)
        {
            RadioButtonList rblMultipleChoice = (RadioButtonList)row.Cells[0].FindControl(controlID);
            rblMultipleChoice.DataTextField  = "choice_text";
            rblMultipleChoice.DataValueField = "choice_id";
            rblMultipleChoice.DataSourceID   = "dsChoices";
            rblMultipleChoice.DataBind();

            return rblMultipleChoice;
        }

        protected RadioButtonList showTrueFalse(string controlID, GridViewRow row)
        {
            RadioButtonList rblTrueFalse = (RadioButtonList)row.Cells[0].FindControl(controlID);
            rblTrueFalse.DataTextField  = "choice_text";
            rblTrueFalse.DataValueField = "choice_id";
            rblTrueFalse.DataSourceID   = "dsChoices";
            rblTrueFalse.DataBind();

            return rblTrueFalse;
        }

        protected TextBox showFillInTheBlank(string controlID, GridViewRow row)
        {
            return (TextBox)row.Cells[0].FindControl(controlID);
        }

        protected TextBox showShortAnswer(string controlID, GridViewRow row)
        {
            return (TextBox)row.Cells[0].FindControl(controlID);
        }

        protected CheckBoxList showChooseAllThatApply(string controlID, GridViewRow row)
        {
            CheckBoxList cblChooseAllThatApply = (CheckBoxList)row.Cells[0].FindControl(controlID);
            cblChooseAllThatApply.DataTextField = "choice_text";
            cblChooseAllThatApply.DataValueField = "choice_id";
            cblChooseAllThatApply.DataSourceID = "dsChoices";
            cblChooseAllThatApply.DataBind();

            return cblChooseAllThatApply;
        }

        protected DropDownList showMatching(string controlID, GridViewRow row)
        {
            DropDownList ddlMatching = (DropDownList)row.Cells[0].FindControl(controlID);
            ddlMatching.DataTextField = "choice_text";
            ddlMatching.DataValueField = "choice_id";
            ddlMatching.DataSourceID = "dsChoices";
            ddlMatching.DataBind();

            return ddlMatching;
        }

        protected TextBox showPledgeStatement(string controlID, GridViewRow row)
        {
            return (TextBox)row.Cells[0].FindControl(controlID);
        }

        protected TextBox showEssay(string controlID, GridViewRow row)
        {
            return (TextBox)row.Cells[0].FindControl(controlID);
        }

        #endregion

        #region _Get Functions_

        protected string getCorrectAnswerID(string questionID)
        {
            OracleCommand cmdGetCorrectAnswerID = new OracleCommand(@"
SELECT c.choice_id
  FROM choice c
 WHERE c.choice_id = questions.getQuestionAnswerID(p_QuestionID => :p_QuestionID)",
                new OracleConnection(ConfigurationManager.ConnectionStrings["Singularity"].ConnectionString));
            cmdGetCorrectAnswerID.Parameters.Add("p_QuestionID", questionID);

            cmdGetCorrectAnswerID.Connection.Open();
            string answerID = Convert.ToString(cmdGetCorrectAnswerID.ExecuteScalar());
            cmdGetCorrectAnswerID.Connection.Close();

            return answerID;
        }

        protected string getCorrectAnswerText(string answerID)
        {
            OracleCommand cmdGetCorrectAnswerText = new OracleCommand(@"
SELECT c.choice_text
  FROM choice c
 WHERE c.choice_id = :p_AnswerID",
                new OracleConnection(ConfigurationManager.ConnectionStrings["Singularity"].ConnectionString));
            cmdGetCorrectAnswerText.Parameters.Add("p_AnswerID", answerID);

            cmdGetCorrectAnswerText.Connection.Open();
            string answerText = Convert.ToString(cmdGetCorrectAnswerText.ExecuteScalar());
            cmdGetCorrectAnswerText.Connection.Close();

            return answerText;
        }

        protected string getStudentResponse(string questionID)
        {
            OracleCommand cmdGetStudentResponse = new OracleCommand(@"
SELECT NVL(TO_CHAR(r.choice_id), r.response_text) AS response
  FROM response r
 WHERE r.student_id  = :p_StudentID
   AND r.question_id = :p_QuestionID",
                new OracleConnection(ConfigurationManager.ConnectionStrings["Singularity"].ConnectionString));
            cmdGetStudentResponse.Parameters.Add("p_StudentID", Convert.ToString(Session["UserID"]));
            cmdGetStudentResponse.Parameters.Add("p_QuestionID", questionID);

            cmdGetStudentResponse.Connection.Open();
            string response = Convert.ToString(cmdGetStudentResponse.ExecuteScalar());
            cmdGetStudentResponse.Connection.Close();

            return response;
        }

        protected string getStudentName()
        {
            OracleCommand cmdGetStudentName = new OracleCommand(@"
SELECT u.user_first_name || ' ' || u.user_last_name AS full_name
  FROM testify_user u
 WHERE u.user_id = :p_StudentID",
                new OracleConnection(ConfigurationManager.ConnectionStrings["Singularity"].ConnectionString));
            cmdGetStudentName.Parameters.Add("p_StudentID", Convert.ToString(Session["UserID"]));

            cmdGetStudentName.Connection.Open();
            string name = Convert.ToString(cmdGetStudentName.ExecuteScalar());
            cmdGetStudentName.Connection.Close();

            return name;
        }

        #endregion
    }
}